package city.spring.modules.system.service.impl;

import city.spring.modules.system.entity.ClientEntity;
import city.spring.modules.system.model.ClientDetailsDTO;
import city.spring.modules.system.service.ClientService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Primary;
import org.springframework.security.oauth2.provider.*;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 客户详细信息服务。
 * 加个 @Primary 为了可以直接使用 ClientDetailsService 注入到其他对象里面
 *
 * @author HouKunLin
 * @date 2019/12/3 0003 9:53
 */
@Primary
@CacheConfig(cacheNames = {ClientServiceImpl.CACHE_NAME})
@Service
public class ClientDetailsServiceImpl implements ClientDetailsService, ClientRegistrationService {
    private static final Logger logger = LoggerFactory.getLogger(ClientDetailsServiceImpl.class);
    private final ClientService clientService;

    public ClientDetailsServiceImpl(ClientService clientService) {
        this.clientService = clientService;
    }

    @Override
    @Cacheable(key = "'info:clientId:'+#clientId")
    public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
        ClientEntity clientEntity = clientService.lambdaQuery().eq(ClientEntity::getClientId, clientId).one();
        if (clientEntity == null) {
            throw new NoSuchClientException("没有客户端请求的id: " + clientId);
        }
        ClientDetailsDTO detailsDTO = new ClientDetailsDTO(clientEntity);
        logger.debug("通过 {} 加载客户端实体类：{}", clientId, clientEntity);
        logger.debug("客户端对应信息：{}", detailsDTO);
        return detailsDTO;
    }

    @Override
    public void addClientDetails(ClientDetails clientDetails) throws ClientAlreadyExistsException {
        logger.debug("添加客户端信息：{}", clientDetails);
    }

    @Override
    public void updateClientDetails(ClientDetails clientDetails) throws NoSuchClientException {
        logger.debug("修改客户端信息：{}", clientDetails);

    }

    @Override
    public void updateClientSecret(String clientId, String secret) throws NoSuchClientException {
        logger.debug("修改客户端密钥：clientId={},secret={}", clientId, secret);

    }

    @Override
    public void removeClientDetails(String clientId) throws NoSuchClientException {
        logger.debug("删除客户端信息：{}", clientId);
        clientService.lambdaUpdate().eq(ClientEntity::getClientId, clientId).remove();
    }

    @Cacheable(key = "'list:all'")
    @Override
    public List<ClientDetails> listClientDetails() {
        List<ClientEntity> clientDetailsEntities = clientService.list();
        List<ClientDetails> clientDetails = clientDetailsEntities.stream()
                .map(ClientDetailsDTO::new)
                .collect(Collectors.toList());
        logger.debug("获取所有客户端实体信息：{}", clientDetailsEntities);
        logger.debug("获取所有客户端信息：{}", clientDetails);
        return clientDetails;
    }

    @PostConstruct
    public void postConstruct() {
        logger.debug("客户详细信息服务: {}", this);
    }
}
